package com.hmsm.server.base;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;

import com.hmsm.server.common.AllContext;
import com.hmsm.sys.bean.LocalUser;
import com.hmsm.sys.service.ILogInfoService;
import com.hmsm.sys.service.IMenuService;
import com.hmsm.sys.service.IRoleInfoService;
import com.hmsm.sys.service.IUserInfoService;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

@SuppressWarnings("serial")
public abstract class BaseAction<U extends LocalUser> extends ActionSupport {
	
	private static final Log log = LogFactory.getLog(ActionSupport.class);
	
	private BaseController baseController;
	
	public BaseController getBaseController() {
		return baseController;
	}

	@Resource
	public void setBaseController(BaseController baseController) {
		// 避免基类对象覆盖子类对象
		if(this.baseController==null||this.baseController.getClass().isAssignableFrom(baseController.getClass())){
			this.baseController = baseController;
		}
	}

	private Boolean ajax;

	public boolean isAjax() {
		if (ajax==null){
			HttpServletRequest request= (HttpServletRequest)ServletActionContext.getRequest();;   
			ajax = "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
			
		}
		return ajax;
	}

	public void setAjax(boolean ajax) {
		this.ajax = ajax;
	}

	public boolean IsMoblie(HttpServletRequest request) {
		boolean isMoblie = false;
		String[] mobileAgents = { "iphone", "android", "phone", "mobile", "wap", "netfront", "java", "opera mobi", "opera mini", "ucweb", "windows ce", "symbian", "series",
				"webos", "sony", "blackberry", "dopod", "nokia", "samsung", "palmsource", "xda", "pieplus", "meizu", "midp", "cldc", "motorola", "foma", "docomo", "up.browser",
				"up.link", "blazer", "helio", "hosin", "huawei", "novarra", "coolpad", "webos", "techfaith", "palmsource", "alcatel", "amoi", "ktouch", "nexian", "ericsson",
				"philips", "sagem", "wellcom", "bunjalloo", "maui", "smartphone", "iemobile", "spice", "bird", "zte-", "longcos", "pantech", "gionee", "portalmmm", "jig browser",
				"hiptop", "benq", "haier", "^lct", "320x320", "240x320", "176x220", "w3c ", "acs-", "alav", "alca", "amoi", "audi", "avan", "benq", "bird", "blac", "blaz", "brew",
				"cell", "cldc", "cmd-", "dang", "doco", "eric", "hipt", "inno", "ipaq", "java", "jigs", "kddi", "keji", "leno", "lg-c", "lg-d", "lg-g", "lge-", "maui", "maxo",
				"midp", "mits", "mmef", "mobi", "mot-", "moto", "mwbp", "nec-", "newt", "noki", "oper", "palm", "pana", "pant", "phil", "play", "port", "prox", "qwap", "sage",
				"sams", "sany", "sch-", "sec-", "send", "seri", "sgh-", "shar", "sie-", "siem", "smal", "smar", "sony", "sph-", "symb", "t-mo", "teli", "tim-", "tosh", "tsm-",
				"upg1", "upsi", "vk-v", "voda", "wap-", "wapa", "wapi", "wapp", "wapr", "webc", "winw", "winw", "xda", "xda-", "Googlebot-Mobile" };
		if (request.getHeader("User-Agent") != null) {
			for (String mobileAgent : mobileAgents) {
				if (request.getHeader("User-Agent").toLowerCase().indexOf(mobileAgent) >= 0) {
					isMoblie = true;
					break;
				}
			}
		}
		return isMoblie;
	}
	
	@Resource
	private IUserInfoService<U, Serializable> userInfoService;

	public IUserInfoService<U, Serializable> getUserInfoService() {
		return userInfoService;
	}

	public void setUserInfoService(IUserInfoService<U, Serializable> userInfoService) {
		this.userInfoService = userInfoService;
	}
	
	@Resource
	private IMenuService menuService;

	public IMenuService getMenuService() {
		return menuService;
	}

	@Resource
	private ILogInfoService logInfoService;
	
	public ILogInfoService getLogInfoService() {
		return logInfoService;
	}

	public void setLogInfoService(ILogInfoService logInfoService) {
		this.logInfoService = logInfoService;
	}

	protected Map<String, Object> mapResult = new HashMap<String, Object>();
	
	public Map<String, Object> getMapResult() {
		return mapResult;
	}

	public void setMapResult(Map<String, Object> mapResult) {
		this.mapResult = mapResult;
	}

	protected List<Object> listResult = new ArrayList<Object>();

	public List<Object> getListResult() {
		return listResult;
	}

	public void setListResult(List<Object> listResult) {
		this.listResult = listResult;
	}
	
	protected String definedResult;
	
	public String getDefinedResult() {
		return definedResult;
	}

	public void setDefinedResult(String definedResult) {
		this.definedResult = definedResult;
	}
	
	protected String message;// 提示信息
	
	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	private File upload;//文件流
	private String uploadFileName;//文件名称
	private String uploadContentType;//文件类型
	private String savePath;//保存位置

	public String getUploadContentType() {
		return uploadContentType;
	}

	public void setUploadContentType(String uploadContentType) {
		this.uploadContentType = uploadContentType;
	}

	public String getUploadFileName() {
		return uploadFileName;
	}

	public void setUploadFileName(String uploadFileName) {
		this.uploadFileName = uploadFileName;
	}

	public File getUpload() {
		return upload;
	}

	public void setUpload(File upload) {
		this.upload = upload;
	}

	public String getSavePath() {
		return savePath;
	}

	public void setSavePath(String savePath) {
		this.savePath = savePath;
	}

	public static Log getLog() {
		return log;
	}

	public boolean log(Object obj, String message) {
		log.info("<<" + obj.getClass() + ":" + message + ">>");
		return true;
	}

	public boolean logError(Object obj, String message) {
		String info = "<<" + obj.getClass() + ":" + message + ">>";
		log.error(info);
		try {
			this.getLogInfoService().save(0, "系统", 0, info);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return true;
	}

	/**
	 * 
	 *  @描述:设置用户到session
	 *  @方法名称:setSessionUser
	 *  @作者:yaosq
	 *  @创建日期:2014-4-1 下午03:49:59 
	 *  @param user
	 *
	 */
	public void setSessionUser(LocalUser user) {
		getBaseController().setSessionUser(user, getHttpSession());
	}

	/**
	 * 
	 *  @描述:从session中获取用户
	 *  @方法名称:getSessionUser
	 *  @作者:yaosq
	 *  @创建日期:2014-4-1 下午03:50:14 
	 *  @return
	 *
	 */
	public U getSessionUser() {
		U obj = getBaseController().getSessionUser(getHttpSession());
		return obj;
	}

	/**
	 * 
	 *  @描述:移除用户
	 *  @方法名称:moveSessionUser
	 *  @作者:yaosq
	 *  @创建日期:2014-4-1 下午03:50:50 
	 *
	 */
	public void moveSessionUser() {
		getBaseController().removeSessionUser(getHttpSession());
	}


	/**
	 * 
	 *  @描述:获取response对象
	 *  @方法名称:getResPonse
	 *  @作者:yaosq
	 *  @创建日期:2014-4-1 下午03:51:01 
	 *  @return
	 *
	 */
	public HttpServletResponse getResPonse() {
		HttpServletResponse response = ServletActionContext.getResponse();
		return response;
	}

	/**
	 * 
	 *  @描述:获取request对象
	 *  @方法名称:getRequest
	 *  @作者:yaosq
	 *  @创建日期:2014-4-1 下午03:51:11 
	 *  @return
	 *
	 */
	public HttpServletRequest getRequest() {
		return ServletActionContext.getRequest();
	}

	/**
	 * 
	 *  @描述:获取httpSession对象
	 *  @方法名称:getHttpSession
	 *  @作者:yaosq
	 *  @创建日期:2014-4-1 下午03:51:22 
	 *  @return
	 *
	 */
	public HttpSession getHttpSession() {
		return this.getRequest().getSession();
	}

	/**
	 * 
	 *  @描述:直接返回带utf-8编码的对象
	 *  @方法名称:writeResponse
	 *  @作者:yaosq
	 *  @创建日期:2014-4-1 下午03:51:35 
	 *  @param message
	 *
	 */
	public void writeResponse(String message) {
		try {
			getResPonse().setContentType("text/html;charset=UTF-8");
			getResPonse().getWriter().write(message);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 
	 *  @描述:获取struts2的session,此session只能struts2范围用，过滤器和jsp页面只能用request中的session
	 *  @方法名称:getSession
	 *  @作者:yaosq
	 *  @创建日期:2014-4-1 下午03:51:59 
	 *  @return
	 *
	 */
	public Map<String, Object> getSession() {
		return ActionContext.getContext().getSession();
	}
	
	/**
	 *  @描述:
	 *  @方法名称:fileNameAppendSuffix
	 *  @作者:fengtao
	 *  @创建日期:2014-4-15 上午11:29:57 
	 *  @param newFileName 新的文件名
	 *  @return
	 **/
	public String fileNameAppendSuffix(String newFileName){
		if(StringUtils.isBlank(uploadFileName) || StringUtils.isBlank(newFileName)){
			return "";
		}
		String suffix = uploadFileName.substring(uploadFileName.lastIndexOf("."), uploadFileName.length());
		return newFileName + suffix;
	}
	
	/**
	 *  @描述:使用Struts2上传单个文件
	 *  @方法名称:uploadFileByStruts2
	 *  @作者:fengtao
	 *  @创建日期:2014-4-15 上午10:22:36 
	 *  @param savePath 保存位置（全路径）
	 *  @param fileName 新文件名称
	 *  @return
	 **/
	public boolean uploadFileByStruts2(String savePath, String newFileName){
		InputStream is = null;
		OutputStream os = null;
		try {
			if(StringUtils.isBlank(savePath) || StringUtils.isBlank(newFileName)){
				log(String.class, "使用Struts2上传文件时：savePath或者newFileName为空！");
				return false;
			}
			//文件夹
			File file = new File(savePath);  
			//如果文件夹不存在则创建 ，上级目录不存在时不能创建成功 
			if(!file.exists() && !file.isDirectory()){     
			    file.mkdir();
			}
			//基于upload创建一个文件输入流
			is = new FileInputStream(upload);
			//设置新文件
			File newFile = new File(savePath, newFileName);
			//创建一个输出流
			os = new FileOutputStream(newFile);
			//设置缓存
			byte[] buffer = new byte[1024];
			int length = 0;
			//读取upload文件输出到newFile文件中
			while ((length = is.read(buffer)) > 0) {
				os.write(buffer, 0, length);
			}
			return true;
		} catch (Exception e) {
			log(e.getClass(), "使用Struts2上传文件失败！");
		} finally {//关闭输入输出流
			try {
				if (os != null) {
					os.close();
				}
				if(is != null){
					is.close();
				}
				System.gc();
			} catch (IOException e) {
				log(e.getClass(), "使用Struts2上传文件时关闭流失败！");
			}
		}
		return false;
	}
	
	/**
	 *  @描述:下载文件
	 *  @方法名称:downloadFile
	 *  @作者:fengtao
	 *  @创建日期:2014-4-15 下午02:13:07 
	 *  @param path 服务器上文件地址（全路径）
	 *  @param newFileName 下载到本地文件名
	 *  @return
	 **/
	public boolean downloadFile(String path, String newFileName){
		OutputStream fos = null;
		InputStream fis = null;
		try {
			//响应到客户端浏览器
			getResPonse().setContentType("application/x-msdownload");//设置response的编码方式
			getResPonse().setHeader("Content-Disposition","attachment;filename="+new String
					(newFileName.getBytes("gbk"),"iso-8859-1"));  
			fis = new FileInputStream(path);
			fos = getResPonse().getOutputStream();
			int bytesRead = 0;
			byte[] buffer = new byte[5 * 1024];
			//将文件发送到客户端
			while ((bytesRead = fis.read(buffer)) != -1) {
				fos.write(buffer, 0, bytesRead);
			}
			return true;
		} catch (Exception e) {
			log(e.getClass(), "下载文件失败！");
			getResPonse().reset();
		} finally {
			try {
				if (fos != null) {
					fos.close();
				}
				if(fis != null){
					fis.close();
				}
				System.gc();
			} catch (IOException e) {
				log(e.getClass(), "下载文件时关闭流失败！");
			}
		}
		return false;
	}

	/**
	 * 检查用户权限
	 * 
	 * @author 舒俊
	 */
	public boolean ck(String code) {
		LocalUser user = getSessionUser();
		try {
			if (user != null && getRoleInfoService().haveRight(code, user)) {
				return true;
			}
		} catch (Exception e) {
			e.printStackTrace();
		} 
		return false;
	}

	public static List<?> findServicesBy(Class<?> class1) {
		return AllContext.findServicesBy(class1);
	}

	// 角色管理
	public static IRoleInfoService getRoleInfoService() {
		return (IRoleInfoService) AllContext.getBeanService(IRoleInfoService.class);
	}

}
